#pragma once
#include "../third_party/httplib.h"
#include "../third_party/json.hpp"
#include "hot_manager.h"
#include "breakpoint_manager.h"
#include <fstream>

using json = nlohmann::json;
using namespace httplib;

class CloudServer {
public:
    CloudServer() : svr() {}

    void setup_routes() {
        svr.Post("/upload", [this](const Request& req, Response& res) {
            std::string filename = req.get_param_value("filename");
            size_t offset = std::stoull(req.get_param_value("offset"));
            std::ofstream ofs("data/" + filename, std::ios::binary | std::ios::app);
            ofs.seekp(offset);
            ofs.write(req.body.c_str(), req.body.size());
            ofs.close();
            bp_mgr.save_progress(filename, offset + req.body.size());
            hot_mgr.access(filename);
            res.set_content("{\"status\":\"ok\"}", "application/json");
        });
        svr.Get("/progress", [this](const Request& req, Response& res) {
            std::string filename = req.get_param_value("filename");
            size_t offset = bp_mgr.get_progress(filename);
            json j = { {"offset", offset} };
            res.set_content(j.dump(), "application/json");
        });
        svr.Get("/hot", [this](const Request& req, Response& res) {
            auto files = hot_mgr.get_hot_files();
            json j = files;
            res.set_content(j.dump(), "application/json");
        });
        svr.Get("/download", [this](const Request& req, Response& res) {
            std::string filename = req.get_param_value("filename");
            std::ifstream ifs("data/" + filename, std::ios::binary);
            if (!ifs) {
                res.status = 404;
                return;
            }
            std::string content((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
            res.set_content(content, "application/octet-stream");
            hot_mgr.access(filename);
        });
    }

    void run(const std::string& host = "0.0.0.0", int port = 8080) {
        system("mkdir data");
        svr.listen(host.c_str(), port);
    }

private:
    Server svr;
    HotFileManager hot_mgr;
    BreakpointManager bp_mgr;
}; 